{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Python Revision and Statistical Methods.ipynb",
      "provenance": [],
      "authorship_tag": "ABX9TyMqF7Vn8LAFss/SvQifF0HO",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/rjrahul24/ai-with-python-series/blob/main/01.%20Getting%20Started%20with%20Python/Python_Revision_and_Statistical_Methods.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jFbbabz4JycZ"
      },
      "source": [
        "**Inheritence in Python**\n",
        "\n",
        "Object Oriented Programming is a coding paradigm that revolves around creating modular code and stopping mulitple uses of the same structure. It is aimed at increasing stability and usability of code. It consists of some well-known concepts stated below:\n",
        "\n",
        "\n",
        "1.   Classes: These often show a collection of functions and attributes that are fastened to a precise name and represent an abstract container.\n",
        "2.   Attributes: Generally, the data that is associated with each class. Examples are variables declared during creation of the class.\n",
        "3. Objects: An instance generated from the class. There can be multiple objects of a class and every individual object takes on the properties of the class. "
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Z25iPYhFJose",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "c42672a9-c10b-4cbd-f75e-bc415258bba8"
      },
      "source": [
        "# Implementation of Classes in Python\n",
        "# Creating a Class Math with 2 functions\n",
        "class Math:\n",
        "  def subtract (self, i, j):\n",
        "    return i-j\n",
        "  def add (self, x, y):\n",
        "    return x+y\n",
        "\n",
        "# Creating an object of the class Math\n",
        "math_child = Math()\n",
        "test_int_A = 10\n",
        "test_int_B = 20\n",
        "print(math_child.subtract(test_int_B, test_int_A))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "10\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "w7yEIH9rVEU3",
        "outputId": "09bf1218-ec9e-40c4-a28b-b92f3abb7663"
      },
      "source": [
        "# Creating a Class Person with an attribute and an initialization function\n",
        "class Person:\n",
        "  name = 'George'\n",
        "  def __init__ (self):\n",
        "    self.age = 34\n",
        "\n",
        "# Creating an object of the class and printing its attributes\n",
        "p1 = Person()\n",
        "print (p1.name)\n",
        "print (p1.age)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "George\n",
            "34\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xDiLDOlQJxVl"
      },
      "source": [
        "**Constructors and Inheritance**\n",
        "\n",
        "The constructor is an initialization function that is always called when a class’s instance is created. The constructor is named __init__() in Python and defines the specifics of instantiating a class and its attributes. \n",
        "Class inheritance is a concept of taking values of a class from its origin and giving the same properties to a child class. It creates relationship models like “Class A is a Class B”, like a triangle (child class) is a shape (parent class). All the functions and attributes of a superclass are inherited by the subclass. \n",
        "1.\tOverriding: During the inheritance, the behavior of the child class or the subclass can be modified. Doing this modification on functions is class “overriding” and is achieved by declaring functions in the subclass with the same name. Functions created in the subclass will take precedence over those in the parent class.\n",
        "2.\tComposition: Classes can also be built from other smaller classes that support relationship models like “Class A has a Class B”, like a Department has Students.\n",
        "3.\tPolymorphism: The functionality of similar looking functions can be changed in run-time, during their implementation. This is achieved using Polymorphism, that includes two objects of different parent class but having the same set of functions. The outward look of these functions is the same, but implementations differ.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZMaenLSWVn7b",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "15c33d92-d7b0-48ae-87d0-df58d4faff12"
      },
      "source": [
        "# Creating a class and instantiating variables\n",
        "class Animal_Dog:\n",
        "    species = \"Canis\"\n",
        "    def __init__(self, name, age):\n",
        "        self.name = name\n",
        "        self.age = age\n",
        "    # Instance method\n",
        "    def description(self):\n",
        "        return f\"{self.name} is {self.age} years old\"\n",
        "    # Another instance method\n",
        "    def animal_sound(self, sound):\n",
        "        return f\"{self.name} says {sound}\"\n",
        "\n",
        "\n",
        "# Check the object’s type\n",
        "Animal_Dog(\"Bunny\", 7)\n",
        "\n",
        "\n",
        "# Even though a and b are both instances of the Dog class, they represent two distinct objects in memory.\n",
        "a = Animal_Dog(\"Fog\", 6)\n",
        "b = Animal_Dog(\"Bunny\", 7)\n",
        "a == b\n",
        "\n",
        "# Instantiating objects with the class’s constructor arguments\n",
        "fog = Animal_Dog(\"Fog\", 6)\n",
        "bunny = Animal_Dog(\"Bunny\", 7)\n",
        "print (bunny.name)\n",
        "\n",
        "print (bunny.age)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Bunny\n",
            "7\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fVQBXiIEufGh",
        "outputId": "c83ef7bd-1dec-45f9-a233-6673a67d3bbd"
      },
      "source": [
        "# Accessing attributes directly\n",
        "print (bunny.species)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Canis\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XD4Oq5Fjukcx",
        "outputId": "000671cd-ad46-464e-9a5b-828c9533fdb3"
      },
      "source": [
        "# Creating a new Object to access through instance functions\n",
        "fog = Animal_Dog(\"Fog\", 6)\n",
        "fog.description()\n",
        "\n",
        "\n",
        "fog.animal_sound(\"Whoof Whoof\")\n",
        "\n",
        "\n",
        "fog.animal_sound(\"Bhoof Whoof\")\n",
        "\n",
        "\n",
        "# Inheriting the Class\n",
        "class GoldRet(Animal_Dog):\n",
        "    def speak(self, sound=\"Warf\"):\n",
        "        return f\"{self.name} says {sound}\"\n",
        "\n",
        "\n",
        "bunny = GoldRet(\"Bunny\", 5)\n",
        "bunny.speak()\n",
        "\n",
        "\n",
        "bunny.speak(\"Grrr Grrr\")\n",
        "\n",
        "\n",
        "# Code Snippet 3: Variables and data types\n",
        "\n",
        "\n",
        "int_var = 100                  # Integer variable\n",
        "float_var  = 1000.0        # Float value\n",
        "string_var  = \"John\"       # String variable\n",
        "print (int_var)\n",
        "\n",
        "\n",
        "print (float_var)\n",
        "\n",
        "print (string_var)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "100\n",
            "1000.0\n",
            "John\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "slVFWumYu0n8"
      },
      "source": [
        "Variables and Data Types in Python\n",
        "\n",
        "Variables are reserved locations in the computer’s memory that store values defined within them. Whenever a variable is created, a piece of the computer’s memory is allocated to it. Based on the data type of this declared variable, the interpreter allocates varied chunks of memory. Therefore, basis the assignment of variables as integer, float, strings, etc. different sizes of memory allocations are invoked.\n",
        "•\tDeclaration: Variables in Python do not need explicit declaration to reserve memory space. This happens automatically when a value is assigned. The (=) sign is used to assign values to variables. \n",
        "•\tMultiple Assignment: Python allows for multiple variables to hold a single value and this declaration can be done together for all variables. \n",
        "•\tDeleting References: Memory reference once created can also be deleted. The 'del' statement is used to delete the reference to a number object. Multiple object deletion is also supported by the 'del' statement.\n",
        "•\tStrings: Strings are a set of characters, that Python allows representation through single or double quotes. String subsets can be formed using the slice operator ([ ] and [:] ) where indexing starts from 0 on the left and -1 on the right. The (+) sign is the string concatenation operator and the (*) sign is the repetition operator.\n",
        "Datatype Conversion\n",
        "Function\tDescription\n",
        "int(x [,base])\tConverts given input to integer. Base is used for string conversions.\n",
        "long(x [,base] )\tConverts given input to a long integer\n",
        "float(x)\tFollows conversion to floating-point number.\n",
        "complex(real [,imag])\tUsed for creating a complex number.\n",
        "str(x)\tConverts any given object to a string\n",
        "eval(str)\tEvaluates given string and returns an object.\n",
        "tuple(s)\tConversion to tuple\n",
        "list(s)\tList conversion of given input\n",
        "set(s)\tConverts the given value to a set\n",
        "unichr(x)\tConversion from an integer to Unicode character.\n",
        "\n",
        "Looking at Variables and Datatypes\n",
        "Data stored as Python’s variables is abstracted as objects. Data is represented by objects or through relations between individual objects. Therefore, every variable and its corresponding values are an object of a class, depending on the stored data.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sUd2krNouqSv",
        "outputId": "b4036486-c01f-4468-b138-93c0aeb1081e"
      },
      "source": [
        "# Multiple Assignment: All are assigned to the same memory location\n",
        "a = b = c = 1\n",
        "# Assigning multiple variables with multiple values\n",
        "a,b,c = 1,2,\"jacob\"\n",
        "\n",
        "\n",
        "# Assigning and deleting variable references\n",
        "var1 = 1\n",
        "var2 = 10\n",
        "\n",
        "\n",
        "del var1                # Removes the reference of var1\n",
        "del var2\n",
        "\n",
        "\n",
        "# Basic String Operations in Python\n",
        "str = 'Hello World!'\n",
        "print (str) \n",
        "\n",
        "\n",
        "# Print the first character of string variable\n",
        "print (str[0])\n",
        "\n",
        "\n",
        "# Prints characters from 3rd to 5th positions\n",
        "print (str[2:5])     \n",
        "\n",
        "\n",
        "# Print the string twice\n",
        "print (str * 2)\n",
        "\n",
        "\n",
        "# Concatenate the string and print\n",
        "print (str + \"TEST\")"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Hello World!\n",
            "H\n",
            "llo\n",
            "Hello World!Hello World!\n",
            "Hello World!TEST\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dGldhEOHu8B9"
      },
      "source": [
        ""
      ],
      "execution_count": null,
      "outputs": []
    }
  ]
}